<template>
    <playlist-main
        :playlist="starlist"
        :selected="selected"
        @toggle-play="togglePlay"
        @add="addMidiItems"
        @delete="deleteMidiItems"
        @move-up="moveUp"
        @move-down="moveDown"
        @update-star="updateStar"
    />
</template>

<script setup lang="ts">
import { ref, reactive, computed, watchEffect } from "vue";
import { useRouter } from "vue-router";
import { MidiItem } from "@/lib/midi";
import { Playlist } from "@/lib/playlist";
import { injectMessageState } from "@/lib/view";
import useStarStroe from "@/store/star";
import usePlaylistStore from "@/store/playlist";
import PlaylistMain from "@/components/playlist/PlaylistMain.vue";

const router = useRouter();

const star = useStarStroe();
const playlist = usePlaylistStore();

// 收藏列表名
const name = computed(() => {
    const name = router.currentRoute.value.params.name ?? "";

    // 如果 name 是 string[]
    // 只取第一个元素
    if (Array.isArray(name)) {
        if (name.length === 0) {
            return "";
        }
        return name[0];
    }

    return name;
});

// 收藏列表
const starlist = ref(Playlist.object());

// 选中的 MidiItem
const selected = reactive(new Set<number>());

// 全局消息状态
const messageState = injectMessageState();

watchEffect(async () => {
    // 收藏列表为空
    if (name.value === "") {
        starlist.value = Playlist.object();
        return;
    }

    // 读取收藏列表失败
    // 返回上一级页面
    const list = await star.load(name.value);
    if (list === undefined) {
        messageState.visible = true;
        messageState.text = `读取收藏列表 “${name.value}” 失败`;
        router.back();
        return;
    }

    // 读取成功
    starlist.value = list;
});

/**
 * 切换播放状态
 * @param index 索引
 */
async function togglePlay(index: number) {
    // 收藏列表名为空
    if (name.value === "") {
        return;
    }

    // 把当前项添加到播放列表并进行播放
    starlist.value.focus = index;
    await playlist.insert(starlist.value.items[index]);
    await playlist.setFocus(playlist.length - 1);
    await playlist.togglePause();
}

/**
 * 添加 MidiItem
 * @param items MidiItem
 */
async function addMidiItems(...items: MidiItem[]) {
    // 收藏列表名为空
    if (name.value === "") {
        return;
    }

    // 添加到收藏列表
    for (const item of items) {
        Playlist.insert(starlist.value, item);
    }

    // 保存收藏列表
    await star.save(name.value, starlist.value);
}

/**
 * 删除选中的 MidiItem
 * @param indexes 索引
 */
async function deleteMidiItems(...indexes: number[]) {
    // 收藏列表名为空
    if (name.value === "") {
        return;
    }

    // 清空收藏列表
    if (indexes.length === starlist.value.items.length) {
        Playlist.removeAll(starlist.value);
    } else {
        Playlist.remove(starlist.value, ...indexes);
    }

    // 保存收藏列表
    await star.save(name.value, starlist.value);
}

/**
 * 上移 MidiItem
 * @param index 索引
 */
async function moveUp(index: number) {
    // 收藏列表名为空
    if (name.value === "") {
        return;
    }

    // 上移
    Playlist.swap(starlist.value, index - 1, index);

    // 保存收藏列表
    await star.save(name.value, starlist.value);
}

/**
 * 下移 MidiItem
 * @param index 索引
 */
async function moveDown(index: number) {
    // 收藏列表名为空
    if (name.value === "") {
        return;
    }

    // 下移
    Playlist.swap(starlist.value, index, index + 1);

    // 保存收藏列表
    await star.save(name.value, starlist.value);
}

/**
 * 更新收藏列表
 * @param starName 收藏列表名
 * @param items MidiItem
 */
function updateStar(starName: string, items: MidiItem[]) {
    // 收藏列表名为空
    // 或者收藏列表名与传入的不一致
    if (name.value === "" || name.value !== starName) {
        return;
    }

    // 更新当前收藏列表
    for (const item of items) {
        Playlist.insert(starlist.value, item);
    }
}
</script>
